对 Redux 的代码分割
相信大家都知道利用 React 脚手架 Create React App 构建出来的 React 项目是基于 Webpack 构建的。那么官方也提供了关于拆分 React 代码,实现代码分割的功能。
那么需要使用到的就是 import()
也就是 dynamic import 动态导入功能,配合 React.lazy
进行使用,即可实现代码分割。
关于这一块部分如果你还没有很好的了解,建议你可以看一下《代码分割 - React》。
在我司项目的快迭代环境下,我也选择这套方案来进行优化,但是我在后续的开发过程中发现,这套解决方案并不完善,因为对于 Redux ,我并没有做到代码分割,当迭代过程中仅涉及到修改 Redux reducer 时会出现大批量代码更新。
因为项目中仅使用了一个 store
来使用 Redux ,当里面出现一个细小的变化会导致整个 store
的打包 hash
值变化,从而影响到大部分被分割的 React 代码,包括很多并未做修改的文件。
所以我开始着手对 Redux 进行代码分割,官方《Code Splitting - Redux》也提供了很好的支持。
基于此,我开始修改项目中的代码, 依照官方的例子开始修改:
/**
* rootReducer 即认为静态 reducer
* asyncReducers 即认为需要合并的异步 reducer
*/
const createReducer = asyncReducers => combineReducers({
...rootReducer,
...asyncReducers
});
// 暴露给外界的注入函数
export let injectReducer;
const configureStore = preloadedState => {
const store = createStore(
combineReducers(rootReducer),
preloadedState,
middleware
);
store.asyncReducers = {};
// 注入函数
injectReducer = store.injectReducer = (key, asyncReducer) => {
if (Object.hasOwnProperty.call(store.asyncReducers, key)) { return; };
// 赋值
store.asyncReducers[key] = asyncReducer;
// 合并 reducer 并调用 replaceReducer 方法更新
store.replaceReducer(createReducer(store.asyncReducers));
};
return store;
};
export default configureStore;
对原先的创建 store
过程进行了更新,暴露了 injectReducer
函数用于异步注入,结合 import()
就可以实现对 React 的代码分割,真是非常喜悦。
那我们来看看怎么用:
import { lazy } from 'react';
import { injectReducer } from '@/store/configureStore';
export default {
Something: lazy(async () => {
await import(/* webpackChunkName: 'Something' */'@/reducers/something').then(res => {
injectReducer('something', res.default);
});
return import(/* webpackChunkName: 'Something' */'@/containers/Something');
}),
...
};
使用方法也特别简单,即动态导入后注入 reducer 即可,以实现代码分割。
那么到此,相对实现了一个比较完善的 React + Redux 的代码分割解决方案,可以以页面维度,或者你想要的细度去控制代码分割的程度以应对项目的快迭代。
- 本文链接: https://zongzi531.com/2020/02/27/%E5%AF%B9%20Redux%20%E7%9A%84%E4%BB%A3%E7%A0%81%E5%88%86%E5%89%B2/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!